package com.yenlien.traceyun.plant.dock_device.sjrt;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.yenlien.traceyun.business.dao.BaseSoilDao;
import com.yenlien.traceyun.business.dao.EquipmentDao;
import com.yenlien.traceyun.business.entity.Equipment;
import com.yenlien.traceyun.common.utils.Tools;
import com.yenlien.traceyun.plant.bean.DevDTO;
import com.yenlien.traceyun.plant.dao.AlarmDao;
import com.yenlien.traceyun.plant.dao.DevAlarmDao;
import com.yenlien.traceyun.plant.dao.DevThresholdDao;
import com.yenlien.traceyun.plant.dao.ShiJiRuiTongDao;
import com.yenlien.traceyun.plant.entity.Alarm;
import com.yenlien.traceyun.plant.entity.DevAlarm;
import com.yenlien.traceyun.plant.entity.DevThreshold;
import com.yenlien.traceyun.plant.entity.ShiJiRuiTong;
import com.yenlien.traceyun.webase.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.yenlien.traceyun.plant.dock_device.DevState.EQU_TYPE_KILL_INSECT;
import static com.yenlien.traceyun.plant.dock_device.DevState.TWO_HOURS;
import static com.yenlien.traceyun.plant.dock_device.sjrt.GetCWDevData.getKillInsectUrl;

/**
 * @Date 2022/7/18
 * @Author jiaLong
 * @Descript 获取三丰气象和虫情监控数据，该厂商只有7天内的历史记录  该定时任务部署在自己服务器上才需要执行
 * 虫情监控/杀虫灯/摄像机的HeartbeatTime与当前时间相差一个小时则认为离线，   气象传感/土壤墒情/水质设备的HeartbeatTime与当前时间相差10分钟则离线 （设备列表里返回的HeartbeatTime）
 */

@Component
@Slf4j
public class GetCWDevDataSF {
    private static String appId = "4e32653a9c801fdd";
    private static String AppSecret = "de751f718e52cabfb315e21189fcf5e7";
    public static String token;
    @Autowired
    private ShiJiRuiTongDao shiJiRuiTongDao;
    @Autowired
    private AlarmDao alarmDao;

    @Value("${fruit.level}")
    public String level;

    @Autowired
    private BaseSoilDao baseSoilDao;
    @Autowired
    private EquipmentDao equipmentDao;
    @Autowired
    private DevThresholdDao devThresholdDao;
    @Autowired
    private DevAlarmDao devAlarmDao;


    // 2个小时刷新一次Token
//    @Scheduled(fixedRate = 1000 * 3600 * 2)
    public void reFreshToken() {
        token = getToken();
    }



    public static List<DevDTO> allDev;

    // 请求传感器数据并入库
    @Scheduled(fixedRate = TWO_HOURS, initialDelay = TWO_HOURS)
    public void getData() {
        getToken();
        allDev = getAllDev();
        List<DevDTO> soilList = allDev.stream().filter(x -> "土壤墒情站".equals(x.getDevType())).collect(Collectors.toList());
        List<DevDTO> envList = allDev.stream().filter(x -> "气象监测站".equals(x.getDevType())).collect(Collectors.toList());
        List<Alarm> alarmList = new ArrayList<>();
        for (DevDTO devDTO : envList) {
            List<ShiJiRuiTong> shiJiRuiTongList = setProperty(getNowData(devDTO.getDevId()), "1", devDTO, alarmList);
            // 入库前去重
            List<ShiJiRuiTong> unique = shiJiRuiTongList.stream()
                    .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ShiJiRuiTong::getParamName))), ArrayList::new));
            shiJiRuiTongDao.saveAll(unique);
        }
        // 查询并保存当前土壤墒情数据
        for (DevDTO devDTO : soilList) {
            List<ShiJiRuiTong> unique = getNowData(devDTO.getDevId());
//                    .stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ShiJiRuiTong::getParamName))), ArrayList::new));
            List<ShiJiRuiTong> shiJiRuiTongList = setProperty(unique,  "2", devDTO, alarmList);
            shiJiRuiTongDao.saveAll(shiJiRuiTongList);
        }
//        // 保存预警信息
        if (CollectionUtils.isNotEmpty(alarmList)) {
            alarmDao.saveAll(alarmList);
        }
    }


    //  每天23点59分获取一次虫情数据
    @Scheduled(cron = "0 59 21 * * *")
//    @Scheduled(fixedRate = 1000 * 3600 * 1)
    public void getInsectData() {
        getToken();
        List<DevDTO> allDev = getAllDev();
        List<DevDTO> insectLampList = allDev.stream().filter(x -> EQU_TYPE_KILL_INSECT.equals(x.getDevType())).collect(Collectors.toList());
        List<DevDTO> insectSituationMonitorList = allDev.stream().filter(x -> "虫情测报仪".equals(x.getDevType())).collect(Collectors.toList());
        String today = LocalDate.now().toString();

        for (DevDTO devDTO : insectSituationMonitorList) {
            List<ShiJiRuiTong> insectHistoryData = getInsectHistoryData(devDTO.getDevId(), today, today, GetCWDevData.getInsectHistoryDataUrl);
            List<ShiJiRuiTong> shiJiRuiTongList = setProperty(insectHistoryData, "3", devDTO, null);
//            System.out.println("sfInsect: " + insectHistoryData.size());
            // 解决日期格式问题
            for (ShiJiRuiTong shiJiRuiTong : shiJiRuiTongList) {
                String time = LocalDateTime.parse(shiJiRuiTong.getVal().split("\\.")[0].replace("T", " "), GetCWDevData.formatter).format(GetCWDevData.formatter);
                shiJiRuiTong.setCtime(time);
            }
            shiJiRuiTongDao.saveAll(shiJiRuiTongList);
        }
        //  杀虫灯数据
        for (DevDTO devDTO : insectLampList) {
            List<ShiJiRuiTong> insectHistoryData = getInsectHistoryData(devDTO.getDevId(), today, today, getKillInsectUrl);
//            System.out.println("sfKillInsect: " + insectHistoryData.size());
            shiJiRuiTongDao.saveAll(setProperty(insectHistoryData, "5", devDTO, null));
        }
    }




    public List<ShiJiRuiTong> setProperty(List<ShiJiRuiTong> nowData, Equipment equipment, String type) {
        for (ShiJiRuiTong shiJiRuiTong : nowData) {
            shiJiRuiTong.setType(type);
            shiJiRuiTong.setEquipmentId(equipment.getId());
            shiJiRuiTong.setEquipmentName(equipment.getName());
            shiJiRuiTong.setBaseSoilId(equipment.getMassifId());
            shiJiRuiTong.setCompanyId(equipment.getCompanyId());
        }
        return nowData;
    }

    public List<ShiJiRuiTong> setProperty(List<ShiJiRuiTong> nowData, String type, DevDTO devDTO, List<Alarm> alarmList) {
        Date date = new Date();
        String baseSoilName = "";
        List<DevThreshold> devThresholdList = new ArrayList<>();
        Equipment equipment = null;
        if("2".equals(level)){
            baseSoilName = baseSoilDao.getNameByDevId(devDTO.getDevId());
            equipment = equipmentDao.findBySerial(devDTO.getDevId());
            if(equipment == null){
                log.error("该设备不存在, 序列号： {}", devDTO.getDevId());
            }
            devThresholdList = devThresholdDao.getByCompIdAndEquId(equipment.getCompanyId(), devDTO.getDevId());
        }
        for (ShiJiRuiTong shiJiRuiTong : nowData) {
            shiJiRuiTong.setType(type);
            shiJiRuiTong.setCreateTime(date);
            shiJiRuiTong.setCompanyId("1".equals(level) ? "sf" : "4028814b89ae9d99018acfe6d4060040");
            shiJiRuiTong.setEquipmentId("1".equals(level) ? devDTO.getDevId() : equipment.getId());

            if (!StringUtils.isEmpty(shiJiRuiTong.getParamName()) && shiJiRuiTong.getParamName().contains("温度")  && "1".equals(level)) {
                if (Double.valueOf(shiJiRuiTong.getParamVal()) > GetCWDevData.highTemp) {
//                    if (shiJiRuiTong.getParamName().contains("空气温度"))
//                        alarmList.add(new Alarm("2", shiJiRuiTong.getCtime(), shiJiRuiTong.getParamName(), "*"));
//                    else if (shiJiRuiTong.getParamName().contains("土壤温度"))
//                        alarmList.add(new Alarm("2", shiJiRuiTong.getCtime(), shiJiRuiTong.getParamName(), devDTO.getDevName(), "sf"));
                } else if (Double.valueOf(shiJiRuiTong.getParamVal()) < GetCWDevData.lowTemp) {
//                    if (shiJiRuiTong.getParamName().contains("空气温度"))
//                        alarmList.add(new Alarm("1", shiJiRuiTong.getCtime(), shiJiRuiTong.getParamName(), "*"));
//                    else if (shiJiRuiTong.getParamName().contains("土壤温度"))
//                        alarmList.add(new Alarm("1", shiJiRuiTong.getCtime(), shiJiRuiTong.getParamName(), devDTO.getDevName(), "sf"));
                }
            }
            if("2".equals(level) && org.apache.commons.lang3.StringUtils.isNotBlank(baseSoilName)){
                List<DevAlarm> devAlarmList = new ArrayList<>();
                List<DevThreshold> thresholdList = devThresholdList.stream().filter(x -> x.getType().equals(shiJiRuiTong.getParamName())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(thresholdList)){
                    continue;
                }
                DevThreshold devThreshold = thresholdList.get(0);
                if(devThreshold != null){
                    Double high = devThreshold.getHigh();
                    Double low = devThreshold.getLow();
                    Double paramVal = Double.valueOf(shiJiRuiTong.getParamVal());
                    if(paramVal > high || paramVal < low){
                        DevAlarm devAlarm = new DevAlarm();
                        devAlarm.setDevId(devDTO.getDevId());
                        devAlarm.setDevName(equipment.getName());
                        devAlarm.setDevType(equipment.getType());
                        devAlarm.setParamName(shiJiRuiTong.getParamName());
                        devAlarm.setVal(shiJiRuiTong.getParamVal()  + shiJiRuiTong.getParamUnit());
                        devAlarm.setThreshold(low + "~" + high + shiJiRuiTong.getParamUnit());
                        devAlarm.setCompId(equipment.getCompanyId());
                        devAlarm.setHandleState("1");
                        devAlarm.setBaseSoilName(baseSoilName);
                        devAlarm.setCreateTime(Tools.DATE_TIME_FORMAT.format(date));
                        devAlarm.setAlarmType("1");
                        if(paramVal > high){
                            devAlarm.setTitle(shiJiRuiTong.getParamName() + "高于最大值: " + high);
                        }
                        if(paramVal < low){
                            devAlarm.setTitle(shiJiRuiTong.getParamName() + "低于最小值: " + low);
                        }
                        if(CollectionUtils.isEmpty(devAlarmDao.getIdByParamNameAndDevId(shiJiRuiTong.getParamName(), devDTO.getDevId()))){
                            devAlarmList.add(devAlarm);
                        }
                    }
                }
                devAlarmDao.saveAll(devAlarmList);
            }
        }
        return nowData;
    }


    public static List<ShiJiRuiTong> getNowData(String devId) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        String result = HttpRequest.post(GetCWDevData.getNowDataUrl).body(JSONObject.toJSONString(param))
//                .header("Authorization", StringUtils.isEmpty(token) ? "Bearer " + getToken() : token).execute().body();
//                .header("Authorization", "Bearer " + getToken()).execute().body();
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
//            System.out.println("dev: " + devId + "    ," + JSONObject.parseObject(result).getString("Data"));
            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), ShiJiRuiTong.class);
        } else {
            log.error("获取当前数据失败, AppId为: {}", appId);
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }

    // Val   Up:上；down:下；left:左；right:右；zoomin:放大；zoomout:缩小
    public static boolean videoMove(String devId, String val) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        param.put("Val", val);
        String result = HttpRequest.post(GetCWDevData.videoMove).body(JSONObject.toJSONString(param))
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return true;
        } else {
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }

    public static boolean videoMove(String devId, String val, String token) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        param.put("Val", val);
        String result = HttpRequest.post(GetCWDevData.videoMove).body(JSONObject.toJSONString(param))
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return true;
        } else {
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }

    public static String getVideo(String devId) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        String result = HttpRequest.post(GetCWDevData.getVideoUrl).body(JSONObject.toJSONString(param))
//                .header("Authorization", StringUtils.isEmpty(token) ? "Bearer " + getToken() : token).execute().body();
//                .header("Authorization", "Bearer " + getToken()).execute().body();
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
//            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), ShiJiRuiTong.class);
            return JSONObject.parseObject(result).getString("Data");
        } else {
            log.error("获取播放地址失败, AppId为: {}", appId);
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }


    public static List<ShiJiRuiTong> getEnvHistoryData(String devId, String beginDate, String endDate) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        param.put("Bdate", beginDate);
        param.put("Edate", endDate);
        String result = HttpRequest.post(GetCWDevData.getHistoryDataUrl).body(JSONObject.toJSONString(param))
//                .header("Authorization", StringUtils.isBlank(token) ? "Bearer " + getToken() : token).execute().body();
//                    .header("Authorization", "Bearer " + getToken()).execute().body();
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), ShiJiRuiTong.class);
        } else {
            log.error("获取气象历史数据失败, AppId为: {}", appId);
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }


    public static List<ShiJiRuiTong> getInsectHistoryData(String devId, String Bdate, String Edate, String url) {
        Map<String, String> param = new HashMap<>();
        param.put("DevId", devId);
        param.put("Bdate", Bdate);
        param.put("Edate", Edate);
        String result = HttpRequest.post(url).body(JSONObject.toJSONString(param))
//                .header("Authorization", StringUtils.isBlank(token) ? "Bearer " + getToken() : token).execute().body();
//                .header("Authorization", "Bearer " + getToken()).execute().body();
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), ShiJiRuiTong.class);
        } else {
            log.error("获取虫情监控历史数据失败, AppId为: {}", appId);
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }


    public static List<DevDTO> getAllDev() {
//        getToken();
        Map<String, String> param = new HashMap<>();
        param.put("FunCode", "");
        String result = HttpRequest.post(GetCWDevData.getAllDevUrl).body(JSONObject.toJSONString(param))
//                .header("Authorization", StringUtils.isEmpty(token) ? "Bearer " + getToken() : token).execute().body();
//                .header("Authorization", "Bearer " + getToken()).execute().body();
                .header("Authorization", "Bearer " + token).execute().body();
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            // (now - heartbeatTime) > 即代表离线，否则为在线
            // 虫情监控/杀虫灯/摄像机的HeartbeatTime与当前时间相差一个小时则认为离线，   气象传感/土壤墒情/水质设备的HeartbeatTime与当前时间相差10分钟则离线
            return JSONObject.parseArray(JSONObject.parseObject(result).getString("Data"), DevDTO.class);
        } else {
            log.error("获取设备列表失败, AppId为: {}", appId);
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }

    public static String getToken() {
        Map<String, String> loginParam = new HashMap<>();
        loginParam.put("AppId", appId);
        loginParam.put("AppSecret", AppSecret);
        String result = HttpUtil.post(GetCWDevData.getTokenUrl, JSONObject.toJSONString(loginParam));
        boolean isSuccess = JSONObject.parseObject(result).getBoolean("IsSuccess");
        if (isSuccess) {
            token = JSONObject.parseObject(result).getJSONObject("Data").getString("Token");
            return token;
        } else {
            log.error("获取Token失败, AppId为: {}", appId);
            throw new BusinessException(JSONObject.parseObject(result).getString("Msg"));
        }
    }


    public static void main(String[] args) {

//        try {
//            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
//            while (interfaces.hasMoreElements()) {
//                NetworkInterface networkInterface = interfaces.nextElement();
//                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
//                while (addresses.hasMoreElements()) {
//                    InetAddress address = addresses.nextElement();
//                    if (!address.isLoopbackAddress() && address.isSiteLocalAddress()) {
//                        System.out.println("Public IP Address: " + address.getHostAddress());
//                    }
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }




        getToken();
        List<DevDTO> allDev = getAllDev();
        System.out.println(allDev.stream().collect(Collectors.groupingBy(DevDTO::getDevType, Collectors.counting())));
//        getNowData("866250060503087").stream()
//                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ShiJiRuiTong::getParamName))), ArrayList::new)).forEach(System.out::println);
//        List<DevDTO> soilList = allDev.stream().filter(x -> "土壤墒情站".equals(x.getDevType())).collect(Collectors.toList());
//        List<DevDTO> insectLampList = allDev.stream().filter(x -> EQU_TYPE_KILL_INSECT.equals(x.getDevType())).collect(Collectors.toList());
//        List<DevDTO> insectSituationMonitorList = allDev.stream().filter(x -> "虫情测报仪".equals(x.getDevType())).collect(Collectors.toList());
//        List<DevDTO> envList = allDev.stream().filter(x -> "气象监测站".equals(x.getDevType())).collect(Collectors.toList());

//        List<DevDTO> envList = allDev.stream().filter(x -> EQU_TYPE_VIDEO.equals(x.getDevType())).collect(Collectors.toList());
//            allDev.forEach(System.out::println);
//        System.out.println(getVideo("D83590999-D1"));

        String today = LocalDate.now().minusDays(1).toString();
        String yesterday = LocalDate.now().minusDays(7).toString();
//        getInsectHistoryData("866250061177683", yesterday, today, getKillInsectUrl).forEach(System.out::println);
//        getInsectHistoryData("866250061058131", yesterday, today, getKillInsectUrl).forEach(System.out::println);
//        getInsectHistoryData("866250061176222", yesterday, today, getKillInsectUrl).forEach(System.out::println);

//        System.out.println(allDev);
//        System.out.println(getEnvHistoryData(soilList.get(0).getDevId(), yesterday, today));
//        System.out.println(getNowData(envList.get(0).getDevId()));
//        System.out.println(getNowData("866250061183327"));
//        System.out.println(allDev);
//        for(DevDTO dev : insectSituationMonitorList){
//            System.out.println(getInsectHistoryData(dev.getDevId(), yesterday, today));
//        }
//
//        System.out.println("------------------------------");
//        for(DevDTO dev : insectLampList){
//            System.out.println(getNowData(dev.getDevId()));
//        }
//
//        System.out.println("------------------------------");
//        for(DevDTO dev : soilList){
//            System.out.println(getNowData(dev.getDevId()));
//        }
//
//
//        System.out.println("------------------------------");
//        for(DevDTO dev : envList){
//            System.out.println(getNowData(dev.getDevId()));
//        }
//
//        System.out.println("------------------------------");
//        for(DevDTO dev : envList){
//            System.out.println(getInsectHistoryData(dev.getDevId(), yesterday, today));
//        }

//        System.out.println(getCWDevData.getAllDev());


    }


}
